package com.yyk.yiliao.util.pay;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;

import com.orhanobut.logger.Logger;
import com.tencent.mm.opensdk.modelpay.PayReq;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import com.yyk.yiliao.config.Constant;
import com.yyk.yiliao.bean.WechatUnifiedorder_Info;
import com.yyk.yiliao.wxapi.WXPayEntryActivity;

import java.security.MessageDigest;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 * 微信支付
 */

public class PayUtils2 {
    private IWXAPI mWxApi;

    private Context mContext;
    private static volatile PayUtils2 mPayUtils = null;

    private PayUtils2(Context context) {
        this.mContext = context;
        mWxApi = WXAPIFactory.createWXAPI(mContext, Constant.WEIXIN_APP_ID, true);
        // 将该app注册到微信
        mWxApi.registerApp(Constant.WEIXIN_APP_ID);
    }

    public static PayUtils2 getInstance(Context context) {
        if (mPayUtils == null) {
            synchronized (PayUtils.class) {
                if (mPayUtils == null) mPayUtils = new PayUtils2(context);
            }
        }
        return mPayUtils;
    }

    /**
     * 微信支付回掉
     */
    public interface WXBack {
        void payBack(boolean status);
    }

    public WXBack wxBack;

    public void setWxBack(WXBack wxBack) {
        this.wxBack = wxBack;
    }

    /**
     * 微信支付成功或失败的通知
     */
    private BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            try {
                boolean booleanExtra = intent.getBooleanExtra("success", false);
                if (wxBack != null) {
                    wxBack.payBack(booleanExtra);
                }
            } catch (Exception e) {
                context.unregisterReceiver(receiver);
            }
            context.unregisterReceiver(receiver);
        }
    };


    /**
     * 微信支付操作
     *
     * @param info
     */


    public void invokeWxPay(WechatUnifiedorder_Info info) {

        PayReq req = new PayReq();
        req.appId = Constant.WEIXIN_APP_ID;                         //微信开放平台审核通过的应用APPID
        req.partnerId = Constant.WEIXIN_APP_NUMBER;                             //微信支付分配的商户号
        req.prepayId = info.getData();                              //预支付交易会话ID
//        req.nonceStr = NumberUtils.createRandomString(false, 16);                               //随机字符串，不长于32位。
        req.nonceStr = getRandomStringByLength(16);                               //随机字符串，不长于32位。
        req.timeStamp = System.currentTimeMillis() / 1000 + "";   //时间戳
        req.packageValue = "Sign=WXPay";                        //扩展字段 暂填写固定值Sign=WXPay
        req.sign = genPayReq(req);                       //二次签名
        mWxApi.sendReq(req);
        Logger.e("info.getData" + info.getData());

        // 注册监听
        mContext.registerReceiver(receiver, new IntentFilter(
                WXPayEntryActivity.ACTION_WX_PAY_RESULT));

    }

    /**
     * 随机字符串
     *
     * @return
     */
    public static String getRandomStringByLength(int length) {
        String base = "abcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }

    /**
     * 获取sign签名
     *
     * @return
     */
    public static String genPayReq(PayReq request) {
        // 把参数的值传进去SortedMap集合里面
        SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();
//      {appid=wx34df375d7dae8c90, noncestr=3BF34EF2CA4A462DB8D4EA48E785CDC3,
//              package=Sign=WXPay, partnerid=1349967601,
//              prepayid=wx2016070910354542c7155d4e0846850809, timestamp=1468031760}
        parameters.put("appid", request.appId);
        parameters.put("noncestr", request.nonceStr);
        parameters.put("package", request.packageValue);
        parameters.put("partnerid", request.partnerId);
        parameters.put("prepayid", request.prepayId);
        parameters.put("timestamp", request.timeStamp);

        String characterEncoding = "UTF-8";
        String mySign = createSign(characterEncoding, parameters);
        Logger.e("--------我的签名-----" + mySign);
        return mySign;
    }

    /**
     * 微信支付签名算法sign
     *
     * @param characterEncoding
     * @param parameters
     * @return
     */
    @SuppressWarnings("unchecked")
    private static String createSign(String characterEncoding, SortedMap<Object, Object> parameters) {
        StringBuffer sb = new StringBuffer();
        Set es = parameters.entrySet();//所有参与传参的参数按照ASCII排序（升序）
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            Object v = entry.getValue();
            if (null != v && !"".equals(v)
                    && !"sign".equals(k) && !"key".equals(k)) {
                sb.append(k + "=" + v + "&");
            }
        }
        sb.append("key=" + Constant.WEIXIN_APP_KEY);
        String sign = MD5Encode(sb.toString(), characterEncoding).toUpperCase();
        return sign;
    }


    private static String byteArrayToHexString(byte b[]) {
        StringBuffer resultSb = new StringBuffer();
        for (int i = 0; i < b.length; i++)
            resultSb.append(byteToHexString(b[i]));

        return resultSb.toString();
    }

    private static String byteToHexString(byte b) {
        int n = b;
        if (n < 0)
            n += 256;
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }

    private static String MD5Encode(String origin, String charsetname) {
        String resultString = null;
        try {
            resultString = new String(origin);
            MessageDigest md = MessageDigest.getInstance("MD5");
            if (charsetname == null || "".equals(charsetname))
                resultString = byteArrayToHexString(md.digest(resultString
                        .getBytes()));
            else
                resultString = byteArrayToHexString(md.digest(resultString
                        .getBytes(charsetname)));
        } catch (Exception exception) {
        }
        return resultString;
    }

    private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};
}
